import { Router } from 'express';
import { query, body } from 'express-validator';
import { authenticateToken } from '../middleware/auth';
import { validateRequest } from '../middleware/validation';
import { prisma } from '../lib/prisma';

const router = Router();

// 全文搜索
router.get('/',
  authenticateToken,
  [
    query('q').isString().trim().notEmpty().withMessage('搜索关键词不能为空'),
    query('page').optional().isInt({ min: 1 }).withMessage('页码必须是正整数'),
    query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('每页数量必须在1-100之间'),
    query('type').optional().isIn(['all', 'title', 'content', 'description']).withMessage('搜索类型无效'),
    query('categoryId').optional().isString(),
    query('tagIds').optional().isString(),
    query('authorId').optional().isString(),
    query('status').optional().isIn(['DRAFT', 'PUBLISHED', 'ARCHIVED']),
    query('dateFrom').optional().isISO8601().withMessage('开始日期格式不正确'),
    query('dateTo').optional().isISO8601().withMessage('结束日期格式不正确'),
    query('sortBy').optional().isIn(['relevance', 'date', 'views', 'likes']).withMessage('排序字段无效'),
    query('sortOrder').optional().isIn(['asc', 'desc']).withMessage('排序顺序无效')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const {
        q: query,
        page = 1,
        limit = 20,
        type = 'all',
        categoryId,
        tagIds,
        authorId,
        status,
        dateFrom,
        dateTo,
        sortBy = 'relevance',
        sortOrder = 'desc'
      } = req.query;

      const skip = (Number(page) - 1) * Number(limit);

      // 构建搜索条件
      const where: any = {};

      // 搜索条件
      if (type === 'all') {
        where.OR = [
          { title: { contains: query as string, mode: 'insensitive' } },
          { description: { contains: query as string, mode: 'insensitive' } },
          { content: { contains: query as string, mode: 'insensitive' } }
        ];
      } else if (type === 'title') {
        where.title = { contains: query as string, mode: 'insensitive' };
      } else if (type === 'content') {
        where.content = { contains: query as string, mode: 'insensitive' };
      } else if (type === 'description') {
        where.description = { contains: query as string, mode: 'insensitive' };
      }

      // 分类筛选
      if (categoryId) {
        where.categoryId = categoryId;
      }

      // 标签筛选
      if (tagIds) {
        const tagIdArray = (tagIds as string).split(',');
        where.tags = {
          some: {
            id: { in: tagIdArray }
          }
        };
      }

      // 作者筛选
      if (authorId) {
        where.authorId = authorId;
      }

      // 状态筛选
      if (status) {
        where.status = status;
      }

      // 日期范围筛选
      if (dateFrom || dateTo) {
        where.createdAt = {};
        if (dateFrom) where.createdAt.gte = new Date(dateFrom as string);
        if (dateTo) where.createdAt.lte = new Date(dateTo as string);
      }

      // 构建排序条件
      let orderBy: any = {};
      if (sortBy === 'relevance') {
        // 相关性排序（标题匹配 > 描述匹配 > 内容匹配）
        orderBy = [
          { title: { contains: query as string } ? 'desc' : 'asc' },
          { description: { contains: query as string } ? 'desc' : 'asc' },
          { createdAt: 'desc' }
        ];
      } else if (sortBy === 'date') {
        orderBy = { createdAt: sortOrder };
      } else if (sortBy === 'views') {
        orderBy = { viewCount: sortOrder };
      } else if (sortBy === 'likes') {
        orderBy = { likeCount: sortOrder };
      }

      // 执行搜索
      const [results, total] = await Promise.all([
        prisma.knowledgeBase.findMany({
          where,
          select: {
            id: true,
            title: true,
            description: true,
            slug: true,
            excerpt: true,
            status: true,
            featured: true,
            viewCount: true,
            likeCount: true,
            publishedAt: true,
            createdAt: true,
            updatedAt: true,
            author: {
              select: {
                id: true,
                username: true,
                avatar: true
              }
            },
            category: {
              select: {
                id: true,
                name: true,
                color: true
              }
            },
            tags: {
              select: {
                id: true,
                name: true,
                color: true
              }
            },
            _count: {
              select: {
                likes: true,
                comments: true
              }
            }
          },
          skip,
          take: Number(limit),
          orderBy
        }),
        prisma.knowledgeBase.count({ where })
      ]);

      // 记录搜索日志
      try {
        await prisma.searchLog.create({
          data: {
            query: query as string,
            results: total,
            userId: req.user.id,
            userAgent: req.get('User-Agent') || undefined,
            ipAddress: req.ip || undefined
          }
        });
      } catch (logError) {
        console.error('记录搜索日志失败:', logError);
        // 不影响搜索结果
      }

      res.json({
        code: 200,
        message: '操作成功',
        data: {
          results,
          pagination: {
            page: Number(page),
            limit: Number(limit),
            total,
            pages: Math.ceil(total / Number(limit))
          },
          searchInfo: {
            query,
            type,
            filters: {
              categoryId,
              tagIds,
              authorId,
              status,
              dateFrom,
              dateTo
            },
            sortBy,
            sortOrder
          }
        }
      });
    } catch (error) {
      console.error('搜索失败:', error);
      res.status(500).json({ success: false, error: '搜索失败' });
    }
  }
);

// 高级搜索
router.post('/advanced',
  authenticateToken,
  [
    body('query').optional().isString().trim(),
    body('filters').optional().isObject(),
    body('filters.categories').optional().isArray(),
    body('filters.tags').optional().isArray(),
    body('filters.authors').optional().isArray(),
    body('filters.status').optional().isArray(),
    body('filters.dateRange').optional().isObject(),
    body('filters.dateRange.from').optional().isISO8601(),
    body('filters.dateRange.to').optional().isISO8601(),
    body('sortBy').optional().isIn(['relevance', 'date', 'views', 'likes']),
    body('sortOrder').optional().isIn(['asc', 'desc']),
    body('page').optional().isInt({ min: 1 }),
    body('limit').optional().isInt({ min: 1, max: 100 })
  ],
  validateRequest,
  async (req, res) => {
    try {
      const {
        query,
        filters = {},
        sortBy = 'relevance',
        sortOrder = 'desc',
        page = 1,
        limit = 20
      } = req.body;

      const skip = (Number(page) - 1) * Number(limit);

      // 构建搜索条件
      const where: any = {};

      // 关键词搜索
      if (query) {
        where.OR = [
          { title: { contains: query, mode: 'insensitive' } },
          { description: { contains: query, mode: 'insensitive' } },
          { content: { contains: query, mode: 'insensitive' } }
        ];
      }

      // 分类筛选
      if (filters.categories && filters.categories.length > 0) {
        where.categoryId = { in: filters.categories };
      }

      // 标签筛选
      if (filters.tags && filters.tags.length > 0) {
        where.tags = {
          some: {
            id: { in: filters.tags }
          }
        };
      }

      // 作者筛选
      if (filters.authors && filters.authors.length > 0) {
        where.authorId = { in: filters.authors };
      }

      // 状态筛选
      if (filters.status && filters.status.length > 0) {
        where.status = { in: filters.status };
      }

      // 日期范围筛选
      if (filters.dateRange) {
        if (filters.dateRange.from || filters.dateRange.to) {
          where.createdAt = {};
          if (filters.dateRange.from) {
            where.createdAt.gte = new Date(filters.dateRange.from);
          }
          if (filters.dateRange.to) {
            where.createdAt.lte = new Date(filters.dateRange.to);
          }
        }
      }

      // 构建排序条件
      let orderBy: any = {};
      if (sortBy === 'relevance' && query) {
        orderBy = [
          { title: { contains: query } ? 'desc' : 'asc' },
          { description: { contains: query } ? 'desc' : 'asc' },
          { createdAt: 'desc' }
        ];
      } else if (sortBy === 'date') {
        orderBy = { createdAt: sortOrder };
      } else if (sortBy === 'views') {
        orderBy = { viewCount: sortOrder };
      } else if (sortBy === 'likes') {
        orderBy = { likeCount: sortOrder };
      }

      // 执行搜索
      const [results, total] = await Promise.all([
        prisma.knowledgeBase.findMany({
          where,
          select: {
            id: true,
            title: true,
            description: true,
            slug: true,
            excerpt: true,
            status: true,
            featured: true,
            viewCount: true,
            likeCount: true,
            publishedAt: true,
            createdAt: true,
            updatedAt: true,
            author: {
              select: {
                id: true,
                username: true,
                avatar: true
              }
            },
            category: {
              select: {
                id: true,
                name: true,
                color: true
              }
            },
            tags: {
              select: {
                id: true,
                name: true,
                color: true
              }
            },
            _count: {
              select: {
                likes: true,
                comments: true
              }
            }
          },
          skip,
          take: Number(limit),
          orderBy
        }),
        prisma.knowledgeBase.count({ where })
      ]);

      // 记录搜索日志
      try {
        await prisma.searchLog.create({
          data: {
            query: query || '高级搜索',
            results: total,
            userId: req.user.id,
            userAgent: req.get('User-Agent') || undefined,
            ipAddress: req.ip || undefined
          }
        });
      } catch (logError) {
        console.error('记录搜索日志失败:', logError);
      }

      res.json({
        code: 200,
        message: '操作成功',
        data: {
          results,
          pagination: {
            page: Number(page),
            limit: Number(limit),
            total,
            pages: Math.ceil(total / Number(limit))
          },
          searchInfo: {
            query,
            filters,
            sortBy,
            sortOrder
          }
        }
      });
    } catch (error) {
      console.error('高级搜索失败:', error);
      res.status(500).json({ success: false, error: '高级搜索失败' });
    }
  }
);

// 搜索建议
router.get('/suggestions',
  authenticateToken,
  [
    query('q').isString().trim().notEmpty().withMessage('搜索关键词不能为空'),
    query('limit').optional().isInt({ min: 1, max: 20 }).withMessage('建议数量必须在1-20之间')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { q: query, limit = 10 } = req.query;

      // 获取标题建议
      const titleSuggestions = await prisma.knowledgeBase.findMany({
        where: {
          title: { contains: query as string, mode: 'insensitive' },
          status: 'PUBLISHED'
        },
        select: {
          title: true
        },
        take: Math.ceil(Number(limit) / 2),
        orderBy: { viewCount: 'desc' }
      });

      // 获取标签建议
      const tagSuggestions = await prisma.tag.findMany({
        where: {
          name: { contains: query as string, mode: 'insensitive' }
        },
        select: {
          name: true,
          color: true
        },
        take: Math.ceil(Number(limit) / 2),
        orderBy: {
          knowledgeBases: {
            _count: 'desc'
          }
        }
      });

      // 获取分类建议
      const categorySuggestions = await prisma.category.findMany({
        where: {
          name: { contains: query as string, mode: 'insensitive' }
        },
        select: {
          name: true,
          color: true
        },
        take: Math.ceil(Number(limit) / 3),
        orderBy: {
          knowledgeBases: {
            _count: 'desc'
          }
        }
      });

      const suggestions = {
        titles: titleSuggestions.map(item => item.title),
        tags: tagSuggestions.map(item => ({ name: item.name, color: item.color })),
        categories: categorySuggestions.map(item => ({ name: item.name, color: item.color }))
      };

      res.json({
        code: 200,
        message: '操作成功',
        data: suggestions });
    } catch (error) {
      console.error('获取搜索建议失败:', error);
      res.status(500).json({ success: false, error: '获取搜索建议失败' });
    }
  }
);

// 热门搜索
router.get('/trending',
  authenticateToken,
  [
    query('period').optional().isIn(['day', 'week', 'month']).withMessage('时间周期无效'),
    query('limit').optional().isInt({ min: 1, max: 50 }).withMessage('数量限制必须在1-50之间')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { period = 'week', limit = 20 } = req.query;

      // 计算时间范围
      const now = new Date();
      let startDate: Date;
      
      if (period === 'day') {
        startDate = new Date(now.getTime() - 24 * 60 * 60 * 1000);
      } else if (period === 'week') {
        startDate = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
      } else {
        startDate = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
      }

      // 获取热门搜索词
      const trendingSearches = await prisma.searchLog.groupBy({
        by: ['query'],
        where: {
          createdAt: { gte: startDate }
        },
        _count: { query: true },
        orderBy: {
          _count: {
            query: 'desc'
          }
        },
        take: Number(limit)
      });

      // 获取热门知识库
      const trendingKnowledgeBases = await prisma.knowledgeBase.findMany({
        where: {
          status: 'PUBLISHED',
          createdAt: { gte: startDate }
        },
        select: {
          id: true,
          title: true,
          slug: true,
          viewCount: true,
          likeCount: true,
          category: {
            select: {
              name: true,
              color: true
            }
          }
        },
        orderBy: [
          { viewCount: 'desc' },
          { likeCount: 'desc' }
        ],
        take: Number(limit)
      });

      res.json({
        code: 200,
        message: '操作成功',
        data: {
          period,
          trendingSearches: trendingSearches.map(item => ({
            query: item.query,
            count: item._count.query
          })),
          trendingKnowledgeBases
        }
      });
    } catch (error) {
      console.error('获取热门搜索失败:', error);
      res.status(500).json({ success: false, error: '获取热门搜索失败' });
    }
  }
);

// 搜索历史
router.get('/history',
  authenticateToken,
  [
    query('page').optional().isInt({ min: 1 }).withMessage('页码必须是正整数'),
    query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('每页数量必须在1-100之间')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { page = 1, limit = 20 } = req.query;
      const skip = (Number(page) - 1) * Number(limit);

      const [searchHistory, total] = await Promise.all([
        prisma.searchLog.findMany({
          where: { userId: req.user.id },
          select: {
            id: true,
            query: true,
            results: true,
            createdAt: true
          },
          skip,
          take: Number(limit),
          orderBy: { createdAt: 'desc' }
        }),
        prisma.searchLog.count({ where: { userId: req.user.id } })
      ]);

      res.json({
        code: 200,
        message: '操作成功',
        data: {
          searchHistory,
          pagination: {
            page: Number(page),
            limit: Number(limit),
            total,
            pages: Math.ceil(total / Number(limit))
          }
        }
      });
    } catch (error) {
      console.error('获取搜索历史失败:', error);
      res.status(500).json({ success: false, error: '获取搜索历史失败' });
    }
  }
);

// 清除搜索历史
router.delete('/history',
  authenticateToken,
  async (req, res) => {
    try {
      await prisma.searchLog.deleteMany({
        where: { userId: req.user.id }
      });

      res.json({ code: 200, message: '搜索历史已清除' });
    } catch (error) {
      console.error('清除搜索历史失败:', error);
      res.status(500).json({ success: false, error: '清除搜索历史失败' });
    }
  }
);

export { router as searchRoutes };
